package br.com.felix.svn;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import br.com.felix.commandline.MemoryLog;
import br.com.felix.commandline.SysCommandExecutor;

/**
 * Encapsulates functionalities to query SVN.
 * */
public class SVNClientProxy {

	private String svnRoot;
	private File projectRoot;
	private String projectName;
	private File svnBinFolder;

	/**
	 * Configures the client.
	 * @param svnBinFolder is where the SVN client is installed.
	 * @param svnRepositoryRoot is the "connection string" to SVN, without any project information.
	 * @param projectRoot is the folder in the filesystem that contains the files under source control.
	 * @param projectName is the project name. It is assumed that the SVN URL is formed as projectRoot + projectName.
	 * */
	public SVNClientProxy(File svnBinFolder, String svnRepositoryRoot, File projectRoot, String projectName){
		this.svnRoot = svnRepositoryRoot;
		this.projectRoot = projectRoot;
		this.projectName = projectName;
		this.svnBinFolder = svnBinFolder;
	}
	
	/**
	 * Returns the SVN log for the specified file.
	 * @see Log
	 * */
	public List<Log> getLog(File file) throws IOException, ParseException{
		String svnUrl = svnRoot+"\\"+cutProjetRootPath(file);
		String command = ""+ svnBinFolder.getAbsolutePath()+"\\svn log "+ svnUrl.replaceAll("\\\\", "/");
		System.out.println("Running command:");
		System.out.println(command);
		SysCommandExecutor cmd = new SysCommandExecutor();
		StringBuffer strb = new StringBuffer();
		MemoryLog output = new MemoryLog();
		cmd.setOutputLogDevice(output);
		try {
			cmd.runCommand(command);
		}
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		return parseLogOutput(output);
	}
	
	
	/**
	 * Parses the client output as a Log.
	 * @see Log
	 * */
	private List<Log> parseLogOutput(MemoryLog output) throws IOException, ParseException {
		StringReader reader = new StringReader(output.toString());
		BufferedReader br = new BufferedReader(reader);
		String linha, cabecalho, comentario;
		String campos[], data[];
		List<Log> lstLogs = new ArrayList<Log>();
		Log log;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		while ((linha=br.readLine())!=null){
			if(linha.startsWith("---------")){
				cabecalho = br.readLine();
				if(cabecalho == null)break;
				br.readLine();
				comentario = br.readLine();
				campos = cabecalho.split("\\|");
				log = new Log();
				log.setRevision(campos[0]);
				log.setAuthor(campos[1]);
				data = campos[2].trim().split(" ");
				if(!(data.length<2)){
					log.setDate(sdf.parse(data[0]+" "+data[1]));
				}
				log.setComment(comentario);
				lstLogs.add(log);
			}
		}
		return lstLogs;
	}

	
	/**
	 * Obtains the correspondent path in the repository for a file in the filesystem.
	 * */
	public String cutProjetRootPath(File target){
		String path = target.getAbsolutePath();
		String pathRoot = projectRoot.getAbsolutePath();
		String result = projectName+path.substring(pathRoot.length(),path.length());
		return result;
	}
}
